<script setup>
import { computed, unref } from 'vue'
import { NOOP, isFunction } from '@/utils'

import { useI18n } from 'vue-i18n'
const { t } = useI18n({ useScope: 'global' })

const props = defineProps({
  indexable: {
    type: Boolean,
    default: true
  },
  selectable: {
    type: Boolean,
    default: false
  },
  selected: {
    type: Array,
    default: () => []
  },
  data: {
    required: true,
    type: Array
  },
  columns: {
    required: true,
    type: Array
  },
  actions: {
    type: [Array, Function],
    default: () => []
  },
  actionsWidth: {
    type: Number,
    default: 200
  },
  pagination: {
    type: Object,
    default: () => {}
  },
  currentPage: {
    type: Number,
    default: 1
  },
  pageSize: {
    type: Number,
    default: 10
  },
  total: {
    type: Number,
    default: 0
  },
  pageSizes: {
    type: Array,
    default: () => [10, 20, 30, 50, 100]
  }
})

const emits = defineEmits([
  'onRefresh',
  'update:selected',
  'update:currentPage',
  'update:pageSize'
])

const normalActions = computed(() =>
  isFunction(props.actions) ? props.actions : () => props.actions
)

function handleSelectionChange(val) {
  emits('update:selected', val)
}

function handleSizeChange(val) {
  emits('update:pageSize', val)
  emits('onRefresh')
}
function handleCurrentChange(val) {
  emits('update:currentPage', val)
  emits('onRefresh')
}

const slots = defineSlots()

function normalSlotName(prop) {
  return `prop-${prop}`
}
</script>

<template>
  <el-card shadow="never">
    <template v-if="slots.header" #header>
      <slot name="header"></slot>
    </template>
    <el-table
      v-bind="$attrs"
      :data="data"
      style="width: 100%"
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="props.selectable" type="selection" width="55" />
      <el-table-column
        v-if="props.indexable"
        type="index"
        :label="t('global.index')"
        width="64"
      />
      <el-table-column
        v-for="column in props.columns ?? []"
        :key="column.prop + unref(column.label)"
        v-bind="column"
        :label="unref(column.label)"
      >
        <template v-if="column.type === 'image'" #default="{ row }">
          <DeThumbnail :url="row[column.prop] ?? ''" />
        </template>

        <template
          v-else-if="slots[normalSlotName(column.prop)]"
          #default="scope"
        >
          <slot
            :name="normalSlotName(column.prop)"
            v-bind="{ ...scope, data: scope.row[column.prop] }"
          >
            {{ scope.row[column.prop] }}
          </slot>
        </template>
      </el-table-column>

      <el-table-column
        v-if="props.actions?.length"
        :label="t('global.operation')"
        align="center"
        fixed="right"
        :width="actionsWidth"
      >
        <template #default="{ row }">
          <el-button
            v-for="action in normalActions(row)"
            :key="action.label + action.type"
            v-bind="action"
            link
            :type="action.type"
            @click="action.click?.(row) || NOOP"
          >
            {{ action.label }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="mt-5 flex justify-end">
      <el-pagination
        hide-on-single-page
        layout="total, sizes, prev, pager, next, jumper"
        v-bind="props.pagination"
        v-model:current-page="props.currentPage"
        v-model:page-size="props.pageSize"
        :page-sizes="props.pageSizes"
        :total="props.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </el-card>
</template>
